package cn.changhong.user.filter;


import cn.changhong.user.aop.ResultBean;
import cn.changhong.user.exception.ExpectedTokenException;
import cn.changhong.user.util.TokenAuthenticationService;
import net.sf.json.JSONObject;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.CredentialsExpiredException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * token校验
 *
 * @author itguang
 * @create 2018-01-02 15:16
 **/
public class JWTAuthenticationFilter extends BasicAuthenticationFilter {

    public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }


    /**
     * 在此方法中检验客户端请求头中的token,
     * 如果存在并合法,就把token中的信息封装到 Authentication 类型的对象中,
     * 最后使用  SecurityContextHolder.getContext().setAuthentication(authentication); 改变或删除当前已经验证的 pricipal
     *
     * @param request
     * @param response
     * @param chain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        String a=request.getRequestURI();
        if("/user_manage/user/register".equals(a)){
            chain.doFilter(request, response);
            return;
        }
        if("/user_manage/user/commonUser/forgetPassword".equals(a)){
            chain.doFilter(request, response);
            return;
        }


        try {
            Authentication authentication = TokenAuthenticationService.getAuthentication(request);
            this.onSuccessfulAuthentication(request,response,authentication);
            chain.doFilter(request, response);
        }catch (AuthenticationException e){
            this.onUnsuccessfulAuthentication(request,response,e);
        }
    }
    @Override
    protected void onSuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authResult) throws IOException {
        SecurityContextHolder.getContext().setAuthentication(authResult);
    }
    @Override
    protected void onUnsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter out = response.getWriter();
        ResultBean resultBean;
        if(failed instanceof ExpectedTokenException){
            resultBean=new ResultBean<String>(failed,ResultBean.BAD_REQUEST);
        }else if(failed instanceof CredentialsExpiredException){
            resultBean=new ResultBean<String>(failed,ResultBean.BAD_REQUEST);
        }else {
            resultBean=new ResultBean<String>(failed,0);
        }

        JSONObject jsonObject=JSONObject.fromObject(resultBean);
        out.print(jsonObject.toString());
        out.flush();
        out.close();
    }
}